﻿
using Xacml.Core;
using Xacml.Core.Configuration;
using Xacml.Core.Context;
using Xacml.Core.Interfaces;
using Xacml.Core.Policy;
using Xacml.Core.Runtime.DataTypes;
using Xacml.Core.Runtime.Functions;
using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.XPath;

namespace Xacml.Core.Runtime
{
  public class EvaluationEngine
  {
    private static Hashtable _functions = (Hashtable) null;
    private bool _verbose = true;

    public EvaluationEngine()
    {
      EvaluationEngine.Prepare();
    }

    public EvaluationEngine(bool verbose)
      : this()
    {
      this._verbose = verbose;
    }

    public IDataType GetDataType(string typeId)
    {
      switch (typeId)
      {
        case "urn:oasis:names:tc:xacml:1.0:data-type:x500Name":
          return (IDataType) DataTypeDescriptor.X500Name;
        case "urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name":
          return (IDataType) DataTypeDescriptor.Rfc822Name;
        case "http://www.w3.org/2001/XMLSchema#string":
          return (IDataType) DataTypeDescriptor.String;
        case "http://www.w3.org/2001/XMLSchema#boolean":
          return (IDataType) DataTypeDescriptor.Boolean;
        case "http://www.w3.org/2001/XMLSchema#integer":
          return (IDataType) DataTypeDescriptor.Integer;
        case "http://www.w3.org/2001/XMLSchema#double":
          return (IDataType) DataTypeDescriptor.Double;
        case "http://www.w3.org/2001/XMLSchema#time":
          return (IDataType) DataTypeDescriptor.Time;
        case "http://www.w3.org/2001/XMLSchema#date":
          return (IDataType) DataTypeDescriptor.Date;
        case "http://www.w3.org/2001/XMLSchema#dateTime":
          return (IDataType) DataTypeDescriptor.DateTime;
        case "http://www.w3.org/2001/XMLSchema#anyURI":
          return (IDataType) DataTypeDescriptor.AnyUri;
        case "http://www.w3.org/2001/XMLSchema#hexBinary":
          return (IDataType) DataTypeDescriptor.HexBinary;
        case "http://www.w3.org/2001/XMLSchema#base64Binary":
          return (IDataType) DataTypeDescriptor.Base64Binary;
        case "http://www.w3.org/TR/2002/WD-xquery-operators-20020816#dayTimeDuration":
          return (IDataType) DataTypeDescriptor.DayTimeDuration;
        case "http://www.w3.org/TR/2002/WD-xquery-operators-20020816#yearMonthDuration":
          return (IDataType) DataTypeDescriptor.YearMonthDuration;
        default:
          if (ConfigurationRoot.Config != null)
          {
            foreach (IDataTypeRepository dataTypeRepository in ConfigurationRoot.Config.DataTypeRepositories)
            {
              IDataType dataType = dataTypeRepository.GetDataType(typeId);
              if (dataType != null)
                return dataType;
            }
          }
          return (IDataType) null;
      }
    }

    public IPolicyCombiningAlgorithm CreatePolicyCombiningAlgorithm(string policyCombiningAlgorithmId)
    {
      switch (policyCombiningAlgorithmId)
      {
        case "urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:deny-overrides":
          return (IPolicyCombiningAlgorithm) new PolicyCombiningAlgorithmDenyOverrides();
        case "urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:permit-overrides":
          return (IPolicyCombiningAlgorithm) new PolicyCombiningAlgorithmPermitOverrides();
        case "urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable":
          return (IPolicyCombiningAlgorithm) new PolicyCombiningAlgorithmFirstApplicable();
        case "urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:only-one-applicable":
          return (IPolicyCombiningAlgorithm) new PolicyCombiningAlgorithmOnlyOneApplicable();
        case "urn:oasis:names:tc:xacml:1.1:policy-combining-algorithm:ordered-deny-overrides":
          return (IPolicyCombiningAlgorithm) new PolicyCombiningAlgorithmOrderedDenyOverrides();
        case "urn:oasis:names:tc:xacml:1.1:policy-combining-algorithm:ordered-permit-overrides":
          return (IPolicyCombiningAlgorithm) new PolicyCombiningAlgorithmOrderedPermitOverrides();
        default:
          if (ConfigurationRoot.Config != null)
          {
            foreach (IPolicyCombiningAlgorithmRepository algorithmRepository in ConfigurationRoot.Config.PolicyCombiningAlgorithmRepositories)
            {
              IPolicyCombiningAlgorithm combiningAlgorithm = algorithmRepository.GetPolicyCombiningAlgorithm(policyCombiningAlgorithmId);
              if (combiningAlgorithm != null)
                return combiningAlgorithm;
            }
          }
          return (IPolicyCombiningAlgorithm) null;
      }
    }

    public IRuleCombiningAlgorithm CreateRuleCombiningAlgorithm(string ruleCombiningAlgorithmId)
    {
      switch (ruleCombiningAlgorithmId)
      {
        case "urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:deny-overrides":
          return (IRuleCombiningAlgorithm) new RuleCombiningAlgorithmDenyOverrides();
        case "urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:permit-overrides":
          return (IRuleCombiningAlgorithm) new RuleCombiningAlgorithmPermitOverrides();
        case "urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable":
          return (IRuleCombiningAlgorithm) new RuleCombiningAlgorithmFirstApplicable();
        case "urn:oasis:names:tc:xacml:1.1:rule-combining-algorithm:ordered-deny-overrides":
          return (IRuleCombiningAlgorithm) new RuleCombiningAlgorithmOrderedDenyOverrides();
        case "urn:oasis:names:tc:xacml:1.1:rule-combining-algorithm:ordered-permit-overrides":
          return (IRuleCombiningAlgorithm) new RuleCombiningAlgorithmOrderedPermitOverrides();
        default:
          if (ConfigurationRoot.Config != null)
          {
            foreach (IRuleCombiningAlgorithmRepository algorithmRepository in ConfigurationRoot.Config.RuleCombiningAlgorithmRepositories)
            {
              IRuleCombiningAlgorithm combiningAlgorithm = algorithmRepository.GetRuleCombiningAlgorithm(ruleCombiningAlgorithmId);
              if (combiningAlgorithm != null)
                return combiningAlgorithm;
            }
          }
          return (IRuleCombiningAlgorithm) null;
      }
    }

    public ResponseElement Evaluate(ContextDocument contextDocument)
    {
      EvaluationContext context = new EvaluationContext(this, (PolicyDocument) null, contextDocument);
      try
      {
        if (ConfigurationRoot.Config == null)
          throw new EvaluationException(Resource.ResourceManager[Resource.MessageKey.exc_configuration_file_not_found]);
        PolicyDocument policyDocument = (PolicyDocument) null;
        foreach (IPolicyRepository policyRepository in ConfigurationRoot.Config.PolicyRepositories)
        {
          if (policyDocument != null)
            throw new EvaluationException(Resource.ResourceManager[Resource.MessageKey.exc_duplicated_policy_in_repository]);
          policyDocument = policyRepository.Match(context);
        }
        if (policyDocument != null)
          return this.Evaluate(policyDocument, contextDocument);
        return this.Evaluate((PolicyDocument) null, (ContextDocument) null);
      }
      catch (EvaluationException ex)
      {
        context.Trace("ERR: {0}", (object) ex.Message);
      }
      return this.Evaluate((PolicyDocument) null, (ContextDocument) null);
    }

    public ResponseElement Evaluate(string policyDocument, string contextDocument, XacmlVersion schemaVersion)
    {
      return this.Evaluate((PolicyDocument) PolicyLoader.LoadPolicyDocument((Stream) new FileStream(policyDocument, FileMode.Open), schemaVersion, DocumentAccess.ReadOnly), (ContextDocument) ContextLoader.LoadContextDocument((Stream) new FileStream(contextDocument, FileMode.Open), schemaVersion));
    }

    public ResponseElement Evaluate(PolicyDocument policyDocument, ContextDocument contextDocument)
    {
      EvaluationContext context = new EvaluationContext(this, policyDocument, contextDocument);
      context.Trace("Start evaluation");
      context.AddIndent();
      if (policyDocument == null || contextDocument == null)
        return new ResponseElement(new ResultElement[1]
        {
          new ResultElement((string) null, Decision.Indeterminate, new StatusElement(new StatusCodeElement("urn:oasis:names:tc:xacml:1.0:status:processing-error", (StatusCodeElement) null, policyDocument.Version), (string) null, (string) null, policyDocument.Version), (ObligationCollection) null, policyDocument.Version)
        }, policyDocument.Version);
      if (!policyDocument.IsValidDocument || !contextDocument.IsValidDocument)
        return new ResponseElement(new ResultElement[1]
        {
          new ResultElement((string) null, Decision.Indeterminate, new StatusElement(new StatusCodeElement("urn:oasis:names:tc:xacml:1.0:status:syntax-error", (StatusCodeElement) null, policyDocument.Version), (string) null, (string) null, policyDocument.Version), (ObligationCollection) null, policyDocument.Version)
        }, policyDocument.Version);
      contextDocument.Response = new ResponseElement((ResultElement[]) null, policyDocument.Version);
      try
      {
        IMatchEvaluable matchEvaluable = (IMatchEvaluable) null;
        if (policyDocument.PolicySet != null)
          matchEvaluable = (IMatchEvaluable) new PolicySet(this, (PolicySetElement) policyDocument.PolicySet);
        else if (policyDocument.Policy != null)
          matchEvaluable = (IMatchEvaluable) new Policy(this, (PolicyElement) policyDocument.Policy);
        if (matchEvaluable != null)
        {
          if (matchEvaluable.AllResources.Count == 0)
            matchEvaluable.AllResources.Add("");
          string uriString = string.Empty;
          Uri parent = (Uri) null;
          foreach (Xacml.Core.Context.ResourceElement resourceElement in (CollectionBase) contextDocument.Request.Resources)
          {
            if (resourceElement.IsHierarchical)
            {
              foreach (AttributeElement attributeElement in (CollectionBase) resourceElement.Attributes)
              {
                if (attributeElement.AttributeId == "urn:oasis:names:tc:xacml:1.0:resource:resource-id")
                {
                  if (context.PolicyDocument.Version == XacmlVersion.Version10 || context.PolicyDocument.Version == XacmlVersion.Version11)
                  {
                    uriString = attributeElement.AttributeValues[0].Contents;
                  }
                  else
                  {
                    if (attributeElement.AttributeValues.Count > 1)
                      throw new NotSupportedException("resources contains a bag of values");
                    uriString = attributeElement.AttributeValues[0].Contents;
                  }
                }
              }
              if (uriString != null && uriString.Length != 0)
                parent = new Uri(uriString);
            }
            foreach (string str in matchEvaluable.AllResources)
            {
              bool flag;
              if (resourceElement.IsHierarchical)
              {
                Uri uri = new Uri(str);
                if (!(flag = parent.Equals((object) uri)))
                {
                  if (resourceElement.ResourceScopeValue == ResourceScope.Children)
                    flag = AnyUri.IsChildrenOf(parent, uri);
                  else if (resourceElement.ResourceScopeValue == ResourceScope.Descendants)
                    flag = AnyUri.IsDescendantOf(parent, uri);
                }
                if (flag)
                {
                  foreach (AttributeElementReadWrite elementReadWrite in (CollectionBase) context.CurrentResource.Attributes)
                  {
                    if (elementReadWrite.AttributeId == "urn:oasis:names:tc:xacml:1.0:resource:resource-id")
                    {
                      elementReadWrite.AttributeValues[0].Contents = str;
                      break;
                    }
                  }
                }
              }
              else
              {
                context.CurrentResource = (Xacml.Core.Context.ResourceElementReadWrite) resourceElement;
                flag = true;
              }
              if (flag)
              {
                Decision decision = matchEvaluable.Evaluate(context);
                StatusCodeElement statusCode = !context.IsMissingAttribute ? (!context.ProcessingError ? new StatusCodeElement("urn:oasis:names:tc:xacml:1.0:status:ok", (StatusCodeElement) null, policyDocument.Version) : new StatusCodeElement("urn:oasis:names:tc:xacml:1.0:status:processing-error", (StatusCodeElement) null, policyDocument.Version)) : new StatusCodeElement("urn:oasis:names:tc:xacml:1.0:status:missing-attribute", (StatusCodeElement) null, policyDocument.Version);
                if (!resourceElement.IsHierarchical)
                {
                  IObligationsContainer obligationsContainer = matchEvaluable as IObligationsContainer;
                  contextDocument.Response.Results.Add(new ResultElement("", decision, new StatusElement(statusCode, "", "", policyDocument.Version), obligationsContainer.Obligations, policyDocument.Version));
                  break;
                }
                IObligationsContainer obligationsContainer1 = matchEvaluable as IObligationsContainer;
                contextDocument.Response.Results.Add(new ResultElement(str, decision, new StatusElement(statusCode, "", "", policyDocument.Version), obligationsContainer1.Obligations, policyDocument.Version));
              }
            }
          }
        }
      }
      catch (EvaluationException ex)
      {
        contextDocument.Response = new ResponseElement(new ResultElement[1]
        {
          new ResultElement((string) null, Decision.Indeterminate, new StatusElement(new StatusCodeElement("urn:oasis:names:tc:xacml:1.0:status:processing-error", (StatusCodeElement) null, policyDocument.Version), ex.Message, ex.StackTrace, policyDocument.Version), (ObligationCollection) null, policyDocument.Version)
        }, policyDocument.Version);
      }
      return contextDocument.Response;
    }

    public IFunction GetFunction(string functionId)
    {
      IFunction function1 = (IFunction) EvaluationEngine._functions[(object) functionId];
      if (function1 != null)
        return function1;
      foreach (IFunctionRepository functionRepository in ConfigurationRoot.Config.FunctionRepositories)
      {
        IFunction function2 = functionRepository.GetFunction(functionId);
        if (function2 != null)
          return function2;
      }
      return (IFunction) null;
    }

    public BagValue Resolve(EvaluationContext context, AttributeSelectorElement attributeSelector)
    {
      BagValue bagValue = new BagValue(this.GetDataType(attributeSelector.DataType));
      if ((ResourceContentElement) context.CurrentResource.ResourceContent != null)
      {
        XmlDocument xmlDocument = context.ContextDocument.XmlDocument;
        if (context.ContextDocument.XmlNamespaceManager == null)
          context.ContextDocument.AddNamespaces(context.PolicyDocument.Namespaces);
        try
        {
          string requestContextPath = attributeSelector.RequestContextPath;
          XmlNodeList xmlNodeList = xmlDocument.DocumentElement.SelectNodes(requestContextPath, context.ContextDocument.XmlNamespaceManager);
          if (xmlNodeList != null)
          {
            foreach (XmlNode xmlNode in xmlNodeList)
            {
              Xacml.Core.Policy.AttributeValueElement attributeValueElement = new Xacml.Core.Policy.AttributeValueElement(attributeSelector.DataType, xmlNode.InnerText, attributeSelector.SchemaVersion);
              bagValue.Add((object) attributeValueElement);
            }
          }
        }
        catch (XPathException ex)
        {
          context.Trace("ERR: {0}", (object) ex.Message);
          bagValue = new BagValue(this.GetDataType(attributeSelector.DataType));
        }
      }
      return bagValue;
    }

    public PolicySetElement Resolve(PolicySetIdReferenceElement policyReference)
    {
      if (ConfigurationRoot.Config != null)
      {
        foreach (IPolicyRepository policyRepository in ConfigurationRoot.Config.PolicyRepositories)
        {
          PolicySetElement policySet = policyRepository.GetPolicySet(policyReference);
          if (policySet != null)
            return policySet;
        }
      }
      return (PolicySetElement) null;
    }

    public PolicyElement Resolve(PolicyIdReferenceElement policyReference)
    {
      if (ConfigurationRoot.Config != null)
      {
        foreach (IPolicyRepository policyRepository in ConfigurationRoot.Config.PolicyRepositories)
        {
          PolicyElement policy = policyRepository.GetPolicy(policyReference);
          if (policy != null)
            return policy;
        }
      }
      return (PolicyElement) null;
    }

    public BagValue Resolve(EvaluationContext context, AttributeDesignatorBase attributeDesignator)
    {
      if (attributeDesignator is SubjectAttributeDesignatorElement)
      {
        if (context.ContextDocument.Request != null && context.ContextDocument.Request.Subjects != null)
        {
          BagValue bagValue = new BagValue(this.GetDataType(attributeDesignator.DataType));
          foreach (Xacml.Core.Context.SubjectElement subjectElement in (CollectionBase) context.ContextDocument.Request.Subjects)
          {
            if (((SubjectAttributeDesignatorElement) attributeDesignator).SubjectCategory == null || ((SubjectAttributeDesignatorElement) attributeDesignator).SubjectCategory == subjectElement.SubjectCategory)
            {
              foreach (AttributeElement attributeElement in this.FindAttribute(context, attributeDesignator, (Xacml.Core.Context.TargetItemBase) subjectElement).Elements)
                bagValue.Add((object) attributeElement);
            }
          }
          return bagValue;
        }
      }
      else
      {
        if (attributeDesignator is ResourceAttributeDesignatorElement)
        {
          if (context.ContextDocument.Request != null && context.CurrentResource != null)
            return this.FindAttribute(context, attributeDesignator, (Xacml.Core.Context.TargetItemBase) context.CurrentResource);
          return BagValue.Empty;
        }
        if (attributeDesignator is ActionAttributeDesignatorElement)
        {
          if (context.ContextDocument.Request != null && context.ContextDocument.Request.Action != null)
            return this.FindAttribute(context, attributeDesignator, (Xacml.Core.Context.TargetItemBase) context.ContextDocument.Request.Action);
          return BagValue.Empty;
        }
        if (attributeDesignator is EnvironmentAttributeDesignatorElement)
        {
          if (context.ContextDocument.Request != null && context.ContextDocument.Request.Environment != null)
            return this.FindAttribute(context, attributeDesignator, (Xacml.Core.Context.TargetItemBase) context.ContextDocument.Request.Environment);
          return BagValue.Empty;
        }
      }
      throw new EvaluationException(Resource.ResourceManager[Resource.MessageKey.exc_invalid_attribute_designator]);
    }

    public BagValue FindAttribute(EvaluationContext context, AttributeDesignatorBase attributeDesignator, Xacml.Core.Context.TargetItemBase targetItem)
    {
      BagValue bagValue = new BagValue(this.GetDataType(attributeDesignator.DataType));
      foreach (AttributeElement attributeElement in (CollectionBase) targetItem.Attributes)
      {
        if (attributeElement.Match(attributeDesignator))
        {
          context.Trace("Adding target item attribute designator: {0}", (object) attributeElement.ToString());
          bagValue.Add((object) attributeElement);
        }
      }
      return bagValue;
    }

    public AttributeElement Resolve(EvaluationContext context, TargetMatchBase match, Xacml.Core.Context.TargetItemBase contextTargetItem)
    {
      AttributeElementReadWrite elementReadWrite1 = (AttributeElementReadWrite) null;
      if (match.AttributeReference is AttributeDesignatorBase)
      {
        AttributeDesignatorBase attributeDesignatorBase = (AttributeDesignatorBase) match.AttributeReference;
        context.Trace("Looking for attribute: {0}", (object) attributeDesignatorBase.AttributeId);
        foreach (AttributeElementReadWrite elementReadWrite2 in (CollectionBase) contextTargetItem.Attributes)
        {
          if (elementReadWrite2.Match(attributeDesignatorBase))
          {
            elementReadWrite1 = elementReadWrite2;
            break;
          }
        }
        if (elementReadWrite1 == null)
        {
          context.Trace("Attribute not found, loading searcing an external repository");
          elementReadWrite1 = (AttributeElementReadWrite) this.GetAttribute(context, attributeDesignatorBase, contextTargetItem);
        }
      }
      else if (match.AttributeReference is AttributeSelectorElement)
      {
        AttributeSelectorElement attributeSelectorElement = (AttributeSelectorElement) match.AttributeReference;
        if ((ResourceContentElement) ((Xacml.Core.Context.ResourceElementReadWrite) contextTargetItem).ResourceContent != null)
        {
          XmlDocument xmlDocument = context.ContextDocument.XmlDocument;
          if (context.ContextDocument.XmlNamespaceManager == null)
            context.ContextDocument.AddNamespaces(context.PolicyDocument.Namespaces);
          string requestContextPath = attributeSelectorElement.RequestContextPath;
          try
          {
            XmlNode xmlNode = xmlDocument.DocumentElement.SelectSingleNode(requestContextPath, context.ContextDocument.XmlNamespaceManager);
            if (xmlNode != null)
              elementReadWrite1 = (AttributeElementReadWrite) new AttributeElement((string) null, attributeSelectorElement.DataType, (string) null, (string) null, xmlNode.InnerText, attributeSelectorElement.SchemaVersion);
          }
          catch (XPathException ex)
          {
            context.Trace("ERR: {0}", (object) ex.Message);
            context.ProcessingError = true;
          }
        }
      }
      if (elementReadWrite1 == null && match.AttributeReference.MustBePresent)
        context.IsMissingAttribute = true;
      if (elementReadWrite1 != null)
        return new AttributeElement(elementReadWrite1.AttributeId, elementReadWrite1.DataType, elementReadWrite1.Issuer, elementReadWrite1.IssueInstant, elementReadWrite1.Value, elementReadWrite1.SchemaVersion);
      return (AttributeElement) null;
    }

    public AttributeElement GetAttribute(EvaluationContext context, AttributeDesignatorBase designator, Xacml.Core.Context.TargetItemBase targetItem)
    {
      switch (designator.AttributeId)
      {
        case "urn:oasis:names:tc:xacml:1.0:environment:current-date":
          return new AttributeElement(designator.AttributeId, "http://www.w3.org/2001/XMLSchema#date", (string) null, (string) null, XmlConvert.ToString(System.DateTime.Now, "yyyy-MM-dd"), designator.SchemaVersion);
        case "urn:oasis:names:tc:xacml:1.0:environment:current-time":
          return new AttributeElement(designator.AttributeId, "http://www.w3.org/2001/XMLSchema#time", (string) null, (string) null, XmlConvert.ToString(System.DateTime.Now, "HH:mm:sszzzzzz"), designator.SchemaVersion);
        case "urn:oasis:names:tc:xacml:1.0:environment:current-dateTime":
          return new AttributeElement(designator.AttributeId, "http://www.w3.org/2001/XMLSchema#dateTime", (string) null, (string) null, XmlConvert.ToString(System.DateTime.Now, "yyyy-MM-ddTHH:mm:sszzzzzz"), designator.SchemaVersion);
        default:
          if (ConfigurationRoot.Config != null)
          {
            foreach (IAttributeRepository attributeRepository in ConfigurationRoot.Config.AttributeRepositories)
            {
              AttributeElement attribute = attributeRepository.GetAttribute(context, designator);
              if (attribute != null)
                return attribute;
            }
          }
          return (AttributeElement) null;
      }
    }

    public EvaluationValue EvaluateFunction(EvaluationContext context, IFunction functionInstance, params IFunctionParameter[] arguments)
    {
      if (context.IsMissingAttribute)
      {
        context.Trace("There's a missing attribute in the parameters");
        return EvaluationValue.Indeterminate;
      }
      int index1;
      for (index1 = 0; index1 < functionInstance.Arguments.Length; ++index1)
      {
        if (arguments[index1] is EvaluationValue && ((EvaluationValue) arguments[index1]).IsIndeterminate)
        {
          if (!context.IsMissingAttribute)
            context.ProcessingError = true;
          context.Trace("There's a parameter with Indeterminate value");
          return EvaluationValue.Indeterminate;
        }
        if (functionInstance.Arguments[index1] != arguments[index1].GetType(context) && functionInstance.Arguments[index1] != DataTypeDescriptor.Bag && arguments[index1] is BagValue)
        {
          context.ProcessingError = true;
          context.Trace("There's a parameter with an invalid datatype");
          return EvaluationValue.Indeterminate;
        }
      }
      if (functionInstance.VarArgs)
      {
        int index2 = index1 - 1;
        for (int index3 = index2; index3 < arguments.Length; ++index3)
        {
          if (arguments[index3] is EvaluationValue && ((EvaluationValue) arguments[index3]).IsIndeterminate)
          {
            if (!context.IsMissingAttribute)
              context.ProcessingError = true;
            context.Trace("There's a parameter with Indeterminate value");
            return EvaluationValue.Indeterminate;
          }
          if (functionInstance.Arguments[index2] != arguments[index3].GetType(context) && arguments[index3] is BagValue && functionInstance.Arguments[index2] != DataTypeDescriptor.Bag)
          {
            context.ProcessingError = true;
            context.Trace("There's a parameter with an invalid datatype");
            return EvaluationValue.Indeterminate;
          }
        }
      }
      StringBuilder stringBuilder = new StringBuilder();
      try
      {
        stringBuilder.Append(functionInstance.Id);
        stringBuilder.Append("( ");
        bool flag = true;
        foreach (IFunctionParameter functionParameter in arguments)
        {
          if (flag)
            flag = false;
          else
            stringBuilder.Append(", ");
          stringBuilder.Append(functionParameter.ToString());
        }
        stringBuilder.Append(" )");
        stringBuilder.Append(" = ");
        EvaluationValue evaluationValue = functionInstance.Evaluate(context, arguments);
        stringBuilder.Append(evaluationValue.ToString());
        context.Trace(stringBuilder.ToString());
        return evaluationValue;
      }
      catch (EvaluationException ex)
      {
        context.Trace(stringBuilder.ToString());
        context.ProcessingError = true;
        context.Trace("Error: {0}", (object) ex.Message);
        return EvaluationValue.Indeterminate;
      }
    }

    private static void Prepare()
    {
      if (EvaluationEngine._functions != null)
        return;
      EvaluationEngine._functions = new Hashtable();
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:anyURI-equal", (object) new AnyUriEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:anyURI-bag-size", (object) new AnyUriBagSize());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:anyURI-one-and-only", (object) new AnyUriOneAndOnly());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:anyURI-is-in", (object) new AnyUriIsIn());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:anyURI-bag", (object) new AnyUriBag());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:any-of", (object) new AnyOf());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:any-of-any", (object) new AnyOfAny());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:any-of-all", (object) new AnyOfAll());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:anyURI-at-least-one-member-of", (object) new AnyUriAtLeastOneMemberOf());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:anyURI-intersection", (object) new AnyUriIntersection());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:anyURI-set-equals", (object) new AnyUriSetEquals());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:anyURI-subset", (object) new AnyUriSubset());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:anyURI-union", (object) new AnyUriUnion());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:all-of", (object) new AllOf());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:all-of-any", (object) new AllOfAny());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:all-of-all", (object) new AllOfAll());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:and", (object) new AndFunction());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:base64Binary-equal", (object) new Base64BinaryEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:base64Binary-bag-size", (object) new Base64BinaryBagSize());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:base64Binary-bag", (object) new Base64BinaryBag());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:base64Binary-is-in", (object) new Base64BinaryIsIn());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:base64Binary-one-and-only", (object) new Base64BinaryOneAndOnly());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:base64Binary-at-least-one-member-of", (object) new Base64BinaryAtLeastOneMemberOf());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:base64Binary-intersection", (object) new Base64BinaryIntersection());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:base64Binary-set-equals", (object) new Base64BinarySetEquals());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:base64Binary-subset", (object) new Base64BinarySubset());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:base64Binary-union", (object) new Base64BinaryUnion());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:boolean-equal", (object) new BooleanEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:boolean-bag-size", (object) new BooleanBagSize());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only", (object) new BooleanOneAndOnly());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:boolean-is-in", (object) new BooleanIsIn());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:boolean-bag", (object) new BooleanBag());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:boolean-at-least-one-member-of", (object) new BooleanAtLeastOneMemberOf());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:boolean-intersection", (object) new BooleanIntersection());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:boolean-set-equals", (object) new BooleanSetEquals());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:boolean-subset", (object) new BooleanSubset());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:boolean-union", (object) new BooleanUnion());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:date-equal", (object) new DateEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:date-bag-size", (object) new DateBagSize());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:date-bag", (object) new DateBag());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:date-is-in", (object) new DateIsIn());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:date-one-and-only", (object) new DateOneAndOnly());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:date-greater-than-or-equal", (object) new DateGreaterThanOrEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:date-greater-than", (object) new DateGreaterThan());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:date-less-than-or-equal", (object) new DateLessThanOrEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:date-less-than", (object) new DateLessThan());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:date-add-yearMonthDuration", (object) new DateAddYearMonthDuration());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:date-subtract-yearMonthDuration", (object) new DateSubtractYearMonthDuration());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:date-at-least-one-member-of", (object) new DateAtLeastOneMemberOf());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:date-intersection", (object) new DateIntersection());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:date-set-equals", (object) new DateSetEquals());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:date-subset", (object) new DateSubset());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:date-union", (object) new DateUnion());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dateTime-bag-size", (object) new DateTimeBagSize());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dateTime-bag", (object) new DateTimeBag());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dateTime-equal", (object) new DateTimeEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only", (object) new DateTimeOneAndOnly());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dateTime-is-in", (object) new DateTimeIsIn());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dateTime-greater-than-or-equal", (object) new DateTimeGreaterThanOrEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dateTime-greater-than", (object) new DateTimeGreaterThan());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dateTime-less-than-or-equal", (object) new DateTimeLessThanOrEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dateTime-less-than", (object) new DateTimeLessThan());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dateTime-add-dayTimeDuration", (object) new DateTimeAddDayTimeDuration());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dateTime-add-yearMonthDuration", (object) new DateTimeAddYearMonthDuration());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dateTime-subtract-dayTimeDuration", (object) new DateTimeSubtractDayTimeDuration());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dateTime-subtract-yearMonthDuration", (object) new DateTimeSubtractYearMonthDuration());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dateTime-at-least-one-member-of", (object) new DateTimeAtLeastOneMemberOf());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dateTime-intersection", (object) new DateTimeIntersection());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dateTime-set-equals", (object) new DateTimeSetEquals());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dateTime-subset", (object) new DateTimeSubset());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dateTime-union", (object) new DateTimeUnion());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-equal", (object) new DayTimeDurationEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-bag", (object) new DayTimeDurationBag());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-bag-size", (object) new DayTimeDurationBagSize());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-is-in", (object) new DayTimeDurationIsIn());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-one-and-only", (object) new DayTimeDurationOneAndOnly());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-at-least-one-member-of", (object) new DayTimeDurationAtLeastOneMemberOf());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-intersection", (object) new DayTimeDurationIntersection());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-set-equals", (object) new DayTimeDurationSetEquals());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-subset", (object) new DayTimeDurationSubset());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-union", (object) new DayTimeDurationUnion());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-greater-than-or-equal", (object) new DoubleGreaterThanOrEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-greater-than", (object) new DoubleGreaterThan());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-less-than-or-equal", (object) new DoubleLessThanOrEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-less-than", (object) new DoubleLessThan());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-one-and-only", (object) new DoubleOneAndOnly());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-add", (object) new DoubleAdd());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-multiply", (object) new DoubleMultiply());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-subtract", (object) new DoubleSubtract());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-divide", (object) new DoubleDivide());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-abs", (object) new DoubleAbs());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-to-integer", (object) new DoubleToInteger());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-equal", (object) new DoubleEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-bag-size", (object) new DoubleBagSize());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-bag", (object) new DoubleBag());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-is-in", (object) new DoubleIsIn());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-at-least-one-member-of", (object) new DoubleAtLeastOneMemberOf());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-intersection", (object) new DoubleIntersection());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-set-equals", (object) new DoubleSetEquals());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-subset", (object) new DoubleSubset());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:double-union", (object) new DoubleUnion());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:floor", (object) new Floor());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:hexBinary-equal", (object) new HexBinaryEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:hexBinary-bag-size", (object) new HexBinaryBagSize());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:hexBinary-bag", (object) new HexBinaryBag());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:hexBinary-is-in", (object) new HexBinaryIsIn());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:hexBinary-one-and-only", (object) new HexBinaryOneAndOnly());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:hexBinary-at-least-one-member-of", (object) new HexBinaryAtLeastOneMemberOf());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:hexBinary-intersection", (object) new HexBinaryIntersection());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:hexBinary-set-equals", (object) new HexBinarySetEquals());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:hexBinary-subset", (object) new HexBinarySubset());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:hexBinary-union", (object) new HexBinaryUnion());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-equal", (object) new IntegerEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-bag-size", (object) new IntegerBagSize());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-bag", (object) new IntegerBag());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-is-in", (object) new IntegerIsIn());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal", (object) new IntegerGreaterThanOrEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-greater-than", (object) new IntegerGreaterThan());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal", (object) new IntegerLessThanOrEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-less-than", (object) new IntegerLessThan());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-subtract", (object) new IntegerSubtract());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-add", (object) new IntegerAdd());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-multiply", (object) new IntegerMultiply());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-divide", (object) new IntegerDivide());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-mod", (object) new IntegerMod());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-abs", (object) new IntegerAbs());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-to-double", (object) new IntegerToDouble());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only", (object) new IntegerOneAndOnly());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-at-least-one-member-of", (object) new IntegerAtLeastOneMemberOf());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-intersection", (object) new IntegerIntersection());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-set-equals", (object) new IntegerSetEquals());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-subset", (object) new IntegerSubset());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:integer-union", (object) new IntegerUnion());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:map", (object) new MapFunction());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:not", (object) new NotFunction());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:n-of", (object) new NofFunction());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:or", (object) new OrFunction());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:regexp-string-match", (object) new RegexpStringMatch());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:rfc822Name-equal", (object) new Rfc822NameEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:rfc822Name-bag-size", (object) new Rfc822NameBagSize());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:rfc822Name-bag", (object) new Rfc822NameBag());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:rfc822Name-is-in", (object) new Rfc822NameIsIn());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:rfc822Name-match", (object) new Rfc822NameMatch());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:rfc822Name-one-and-only", (object) new Rfc822NameOneAndOnly());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:rfc822Name-at-least-one-member-of", (object) new Rfc822NameAtLeastOneMemberOf());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:rfc822Name-intersection", (object) new Rfc822NameIntersection());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:rfc822Name-set-equals", (object) new Rfc822NameSetEquals());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:rfc822Name-subset", (object) new Rfc822NameSubset());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:rfc822Name-union", (object) new Rfc822NameUnion());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:round", (object) new Round());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:string-equal", (object) new StringEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:string-one-and-only", (object) new StringOneAndOnly());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:string-is-in", (object) new StringIsIn());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:string-bag-size", (object) new StringBagSize());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:string-bag", (object) new StringBag());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:string-greater-than-or-equal", (object) new StringGreaterThanOrEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:string-greater-than", (object) new StringGreaterThan());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:string-less-than-or-equal", (object) new StringLessThanOrEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:string-less-than", (object) new StringLessThan());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:string-normalize-space", (object) new StringNormalizeSpace());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:string-normalize-to-lower-case", (object) new StringNormalizeToLowerCase());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of", (object) new StringAtLeastOneMemberOf());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:string-intersection", (object) new StringIntersection());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:string-set-equals", (object) new StringSetEquals());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:string-subset", (object) new StringSubset());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:string-union", (object) new StringUnion());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:time-one-and-only", (object) new TimeOneAndOnly());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:time-bag-size", (object) new TimeBagSize());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:time-bag", (object) new TimeBag());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:time-is-in", (object) new TimeIsIn());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:time-equal", (object) new TimeEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:time-greater-than-or-equal", (object) new TimeGreaterThanOrEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:time-greater-than", (object) new TimeGreaterThan());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:time-less-than-or-equal", (object) new TimeLessThanOrEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:time-less-than", (object) new TimeLessThan());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:time-at-least-one-member-of", (object) new TimeAtLeastOneMemberOf());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:time-intersection", (object) new TimeIntersection());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:time-set-equals", (object) new TimeSetEquals());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:time-subset", (object) new TimeSubset());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:time-union", (object) new TimeUnion());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:x500Name-equal", (object) new X500NameEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:x500Name-bag-size", (object) new X500NameBagSize());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:x500Name-bag", (object) new X500NameBag());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:x500Name-is-in", (object) new X500NameIsIn());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:x500Name-match", (object) new X500NameMatch());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:x500Name-one-and-only", (object) new X500NameOneAndOnly());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:x500Name-at-least-one-member-of", (object) new X500NameAtLeastOneMemberOf());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:x500Name-intersection", (object) new X500NameIntersection());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:x500Name-set-equals", (object) new X500NameSetEquals());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:x500Name-subset", (object) new X500NameSubset());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:x500Name-union", (object) new X500NameUnion());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-bag", (object) new YearMonthDurationBag());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-bag-size", (object) new YearMonthDurationBagSize());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-equal", (object) new YearMonthDurationEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-is-in", (object) new YearMonthDurationIsIn());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-one-and-only", (object) new YearMonthDurationOneAndOnly());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-at-least-one-member-of", (object) new YearMonthDurationAtLeastOneMemberOf());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-intersection", (object) new YearMonthDurationIntersection());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-set-equals", (object) new YearMonthDurationSetEquals());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-subset", (object) new YearMonthDurationSubset());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-union", (object) new YearMonthDurationUnion());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:xpath-node-count", (object) new XPathNodeCount());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:xpath-node-equal", (object) new XPathNodeEqual());
      EvaluationEngine._functions.Add((object) "urn:oasis:names:tc:xacml:1.0:function:xpath-node-match", (object) new XPathNodeMatch());
    }
  }
}
